-
Notifications
You must be signed in to change notification settings - Fork 116
Refactor unified_qr.rs to use bitcoin-payment-instructions #607
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Refactor unified_qr.rs to use bitcoin-payment-instructions #607
Conversation
👋 Thanks for assigning @tnull as a reviewer! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, thanks! Did a first ~high-level round. Feel free to undraft this.
src/payment/unified.rs
Outdated
mod tests { | ||
use super::*; | ||
use crate::payment::unified_qr::Extras; | ||
use crate::payment::unified::Extras; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I think we can just drop this line as the super::*
import above covers Extras
. Although, it would actually be preferable to switch to explicit import here, i.e., use super::{Extras, ...}
.
src/payment/unified.rs
Outdated
/// [`Txid`]: bitcoin::hash_types::Txid | ||
#[derive(Debug)] | ||
pub enum QrPaymentResult { | ||
pub enum PaymentResult { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe UnifiedPaymentResult
then?
Cargo.toml
Outdated
|
||
vss-client = "0.3" | ||
prost = { version = "0.11.6", default-features = false} | ||
bitcoin-payment-instructions = { git = "https://github.com/rust-bitcoin/bitcoin-payment-instructions" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, @TheBlueMatt, can we get a bitcoin-payment-instructions
release that includes rust-bitcoin/bitcoin-payment-instructions#6 ?
@chuksys In the meantime, please import a specific commit via rev = ".."
, as otherwise our builds might break as soon as bitcoin-payment-instructions
's main
changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done! You should be able to reference bitcoin-payment-instructions
0.5 now.
src/builder.rs
Outdated
let (stop_sender, _) = tokio::sync::watch::channel(()); | ||
let background_processor_task = Mutex::new(None); | ||
|
||
let hrn_resolver = Arc::new(LDKOnionMessageDNSSECHrnResolver::new(network_graph.clone())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Please use Arc::clone(&..)
here and everywhere for Arc
s. This helps distinguishing that we in fact do not clone the actual value here.
src/payment/unified.rs
Outdated
amount::Amount as BPIAmount, PaymentInstructions, PaymentMethod, | ||
}; | ||
|
||
use crate::types::HRNResolver; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Let's move this up to the other crate::
imports.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please include the test changes in the corresponding commit(s) that require them. Each commit should build and test individually, not just the whole PR.
src/payment/unified.rs
Outdated
pub async fn send( | ||
&self, uri_str: &str, amount_msat: Option<u64>, | ||
) -> Result<PaymentResult, Error> { | ||
let instructions = match PaymentInstructions::parse( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than match
ing, let's just use .map_err(|e| .. )?
, which should make this more readable and less vertical.
Also possible for ~most other match
es below.
src/payment/unified.rs
Outdated
return Err(Error::InvalidAmount); | ||
} | ||
}, | ||
PaymentInstructions::FixedAmount(ref instr) => instr.clone(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we at least check that the amount_msat
(if provided) is greater or equal to the fixed amount?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs a rebase by now, also.
05a948e
to
b4a71f6
Compare
🔔 1st Reminder Hey @tnull! This PR has been waiting for your review. |
🔔 2nd Reminder Hey @tnull! This PR has been waiting for your review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the PR.
I have reviewed this and approve of the refactor. I just have a small note about per-commit compilation and testing where, because of a function signature mismatch between UnifiedPayment
's send
and the bindings-exposed definition, the corresponding commit (16fbedc) that introduced the change failed to compile. In the same vein, albeit not as important, in 7c1a2db, with warnings
enabled, compilation fails because of the unused hrn_resolver
.
Otherwise, this LGTM and I'd be happy to approve this when these are addressed.
src/payment/unified.rs
Outdated
/// | ||
/// [BIP 21]: https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki | ||
pub fn send(&self, uri_str: &str) -> Result<QrPaymentResult, Error> { | ||
pub fn send(&self, uri_str: &str) -> Result<UnifiedPaymentResult, Error> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In 16fbedcc, there's a function signature mismatch between send
and its bindings-exposed definition. The latter is async
and has an optional amount_msat
parameter. The commit does not compile because of this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @enigbe for the review - I have fixed this.
🔔 3rd Reminder Hey @tnull! This PR has been waiting for your review. |
🔔 4th Reminder Hey @tnull! This PR has been waiting for your review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excuse the delay here!
Some comments, but generally looks pretty good as a first step (can't wait for end-to-end tests for the resolution though).
This is also still dependant on a release of bitcoin-payment-instructions
, which, as I hear, should happen really soon though.
src/payment/unified.rs
Outdated
uri_str, | ||
self.config.network, | ||
self.hrn_resolver.as_ref(), | ||
true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We set supports_proof_of_payment_callbacks
to true
here, but never actually handle the callback. This seems like an omission?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll change this to false
for now.
src/payment/unified.rs
Outdated
Error::InvalidAmount | ||
})?; | ||
|
||
let amt = BPIAmount::from_sats(amount).map_err(|e| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we keep the msat
resolution here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! We should use BPIAmount::from_milli_sats
instead - will fix. Thanks for catching that!
src/payment/unified.rs
Outdated
Error::InvalidAmount | ||
})?; | ||
|
||
instr.clone().set_amount(amt, self.hrn_resolver.as_ref()).await.map_err(|e| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can easily avoid these clones
by not taking a ref
:
diff --git a/src/payment/unified.rs b/src/payment/unified.rs
index 68eb55e5..c9f26ee9 100644
--- a/src/payment/unified.rs
+++ b/src/payment/unified.rs
@@ -168,7 +168,7 @@ impl UnifiedPayment {
})?;
let resolved = match instructions {
- PaymentInstructions::ConfigurableAmount(ref instr) => {
+ PaymentInstructions::ConfigurableAmount(instr) => {
let amount = amount_msat.ok_or_else(|| {
log_error!(self.logger, "No amount specified. Aborting the payment.");
Error::InvalidAmount
@@ -179,13 +179,12 @@ impl UnifiedPayment {
Error::InvalidAmount
})?;
- instr.clone().set_amount(amt, self.hrn_resolver.as_ref()).await.map_err(|e| {
+ instr.set_amount(amt, self.hrn_resolver.as_ref()).await.map_err(|e| {
log_error!(self.logger, "Failed to set amount: {:?}", e);
Error::InvalidAmount
})?
},
- PaymentInstructions::FixedAmount(ref instr) => {
- let instr = instr.clone();
+ PaymentInstructions::FixedAmount(instr) => {
if let Some(user_amount) = amount_msat {
if instr.ln_payment_amount().map_or(false, |amt| user_amount < amt.milli_sats())
{
src/payment/unified.rs
Outdated
PaymentInstructions::FixedAmount(ref instr) => { | ||
let instr = instr.clone(); | ||
if let Some(user_amount) = amount_msat { | ||
if instr.ln_payment_amount().map_or(false, |amt| user_amount < amt.milli_sats()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We likely want to compare with max_amount
rather than the LN-specific one, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, comparing with max_amount
makes more sense! Thanks!
src/payment/unified.rs
Outdated
{ | ||
let offer = maybe_wrap(offer.clone()); | ||
let payment_result = if let Some(amount_msat) = amount_msat { | ||
self.bolt12_payment.send_using_amount(&offer, amount_msat, None, None) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please indent by tabs, not spaces. (Not sure how this got past rustfmt
tbh.)
src/payment/unified.rs
Outdated
})?; | ||
|
||
let txid = | ||
self.onchain_payment.send_to_address(&address, amount.sats().unwrap(), None)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be a bug if this ever failed, but please still simply error out if amount.sats()
returns an error.
Thank you! Currently working on the end-to-end test - will open the PR for that asap. |
b4a71f6
to
38e17d1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that lightningdevkit/rust-lightning#3903 was merged, please point this PR to develop
and include a fixup bumping the LDK dependencies to the respective commit hash on LDK main.
We then want to use pay_for_offer_from_hrn
if the parsed payment instructions indicate that the offer was retrieved from an HRN.
Sure, will do. |
This rename reflects that this module is a unified payment interface for both QR code payments and HRN payments passed in as a string without scanning a QR code
…UnifiedPaymentResult These renamings are necessary to reflect the expanded responsibilities for this module.
This commit adds a HRN Resolver to the Node struct which will be useful for resolving HRNs when making BIP 353 payments. It also passes the HRN Resolver into UnifiedPayment.
This commit ensures that when using the unified API to send to a HRN, we use pay_for_offer_from_hrn
This fixup points bitcoin-payment-instructions to my fork allowing me to bump some lightning dependencies in order to resolve dep conflicts here.
…ult to UnifiedPaymentResult
Just fixing some formatting issues.
38e17d1
to
68c33b7
Compare
This fixup commit simply fixes issues with the bolt12 send_using_amount method signature in the tests.
Just fixing a simple formatting issue.
vss-client = "0.3" | ||
prost = { version = "0.11.6", default-features = false} | ||
#bitcoin-payment-instructions = { version = "0.5" } | ||
bitcoin-payment-instructions = { git = "https://github.com/chuksys/bitcoin-payment-instructions", branch = "bump-lightning" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had to point to my fork of bitcoin-payment-instructions
because I had to bump the LDK dependencies there to resolve dependency conflicts here in the develop branch since we bumped the LDK deps here to commit hash 50391d3a3efa7a8f32d119d126a633e4b1981ee6
.
Perhaps we could have a develop branch on https://github.com/rust-bitcoin/bitcoin-payment-instructions
that allows us do the same?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, good point, thanks for bringing it up. I think for this approach here is fine (at least until this PR is getting ready to land), but going forward we might want to figure out a more coherent strategy.
Moving to a develop
branch here does solve some of the issues, but ofc. it's not magic bullet :(
🔔 1st Reminder Hey @tnull! This PR has been waiting for your review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs yet another rebase, as we've been moving fast on the develop
branch. However, we probably want to hold on this until we found a way forward on the end-to-end tests allowing us to verify the whole flow works as expected. Of course feel free to request review in the meantime if you think I should take a look at a specific part!
vss-client = "0.3" | ||
prost = { version = "0.11.6", default-features = false} | ||
#bitcoin-payment-instructions = { version = "0.5" } | ||
bitcoin-payment-instructions = { git = "https://github.com/chuksys/bitcoin-payment-instructions", branch = "bump-lightning" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, good point, thanks for bringing it up. I think for this approach here is fine (at least until this PR is getting ready to land), but going forward we might want to figure out a more coherent strategy.
Moving to a develop
branch here does solve some of the issues, but ofc. it's not magic bullet :(
This PR introduces a
unified.rs
module (which is a refactor of theunified_qr.rs
module) - this refactor allows us to use this module as a single API for sending payments toBIP 21/321 URIs
as well asBIP 353 HRNs
, creating a simpler interface for users.https://github.com/rust-bitcoin/bitcoin-payment-instructions is used to parse
BIP 21/321 URIs
as well as theBIP 353 HRNs
.Changes
unified_qr.rs
module has been renamed tounified.rs.
UnifiedQrPayment
struct has been renamed toUnifiedPayment
.QRPaymentResult
enum has been renamed toUnifiedPaymentResult
.send
method inunified.rs
now supports sending to bothBIP 21/321 URIs
as well asBIP 353 HRNs
.I will follow-up with adding an end-to-end test that asserts that sending to HRNs using this API works.
This PR closes #521